'''

@author: wyndem
@Emil:   wyndem@qq.com
@FileName: aio_requests.py
@Time: 2018/11/9 14:13
@Software: PyCharm
@Description: 

'''
import asyncio
import datetime
from _cffi_backend import string

import vthread as vthread
from aiohttp import ClientSession
from novel.utils.tool import TOOL as t


class Aio(object):

    def __init__(self, urls, func,data=None,method="GET"):
        self.urls = urls
        self.func = func
        self.method=method.upper()
        self.html=''
        self.data=data
        self.retrys_url=[]
        self.retry_num=5

    async def fetch(self, url, session):

        if self.method=="GET":
            async with session.get(url,headers=t.getHeaders()) as response:
                  await self.respones(response,url)

        else:
            async with session.post(url,headers=t.getHeaders()) as response:
                 await self.respones(response,url)

    async  def respones(self,response,url):
        # delay = response.headers.get("DELAY")
        # date = response.headers.get("DATE")
        # t.logging().debug("{}:{} with delay {}".format(date, response.url, delay))
        if response.status >=300 or response.status<200:
            self.retrys_url.append(url)
            t.logging().info('这条请求有问题:{} 状态码为：{}'.format(url,response.status))


        html = await response.read()
        html_map={
            "url":url,
            "html":html,
            "status":response.status
        }

        if self.func == None:
            self.html=html
        else:
            if self.data==None:
                self.func(html_map)
            else:
                self.func(html_map,self.data)

    async def bound_fetch(self, sem, url, session):
        async with sem:
            await self.fetch(url, session)

    def getSemaphore(self,urls):
        if len(urls) <= 500:
            return len(urls)
        else:
            return 500

    async def run(self,urls):

        # url = "http://httpbin.org/get"
        tasks = []
        # create instance of Semaphore
        sem = asyncio.Semaphore(self.getSemaphore(urls))

        # Create client session that will ensure we dont open new connection
        # per each request.
        async with ClientSession() as session:
            for i in urls:
                # pass Semaphore and session to every GET request
                task = asyncio.ensure_future(self.bound_fetch(sem, i, session))
                tasks.append(task)
            responses = asyncio.gather(*tasks)
            await responses
            if self.retry_num>0 and len(self.retrys_url)>0:
                self.retry_num=self.retry_num-1
                retrys_urls=self.retrys_url
                self.retrys_url = []
                await  self.run(retrys_urls)

    def send(self) -> string:
        starttime = datetime.datetime.now()
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        future = asyncio.ensure_future(self.run(self.urls))
        loop.run_until_complete(future)
        endtime = datetime.datetime.now()
        t.logging().info('共耗时{}，发送了{}数据'.format(endtime - starttime,len(self.urls)))
        return self.html



def send_thread(aios):

    @vthread.pool(len(aios))
    def send(a):
        a.send()

    for a in aios:
        send(a)

if __name__ == '__main__':
    html=Aio(['http://httpbin.org/get'],None).send()
    print(html)